package com.novix.portal.framework.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletContext;

import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.lang.StringUtils;

import com.novix.portal.framework.dao.DAOFactory;
import com.novix.portal.framework.dao.IWebContactDAO;
import com.novix.portal.framework.dao.IWebOrganizationDAO;
import com.novix.portal.framework.model.IPortalUser;
import com.novix.portal.framework.model.impl.WebContact;
import com.novix.portal.framework.model.impl.WebOrganization;
import com.novix.portal.framework.util.IConstants;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.NeedsRefreshException;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;

public class ServiceImpl implements IGenericService {
    // private static final int DURATION_IN_SECONDS = 300;
    private static final int DURATION_IN_SECONDS = CacheEntry.INDEFINITE_EXPIRY;

    ServletContext servletContext = null;

    /**
     * Create the service, which includes initializing the persistence framework.
     */
    public ServiceImpl() {
        super();
        init();
    }

    public void setServletContext(ServletContext ctx) {
        this.servletContext = ctx;
    }

    public ServletContext getServletContext() {
        return servletContext;
    }

    /**
     * Log the user out of the system.
     */
    public void logout(String email) {
        // Do nothing with right now, but might want to log it for auditing
        // reasons
    }

    public void destroy() {
        // Do nothing for this example
    }

    /**
     * Opens the database and prepares it for transactions
     */
    private void init() {

    }

    /**
     * @return
     */
    private String getIextensionsPath() {
        return getServletContext().getInitParameter("IEXTENSIONS_PATH");
    }

    /**
     * @return
     */
    private String getDominoServerName() {
        return getServletContext().getInitParameter("DOMINO_SERVER");
    }

    /**
     * @return
     */
    private String getCorbaAddress() {
        return getServletContext().getInitParameter("DominoDIIOPConnection");
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.novix.portal.framework.service.IGenericService#getWebOrganizations()
     */
    public List getWebOrganizations(IPortalUser user) {
        GeneralCacheAdministrator admin = getOSCacheAdmin();
        List list;

        try {
            list = (List) admin.getFromCache(IConstants.WEB_ORGANIZATION_CACHE, DURATION_IN_SECONDS);
        } catch (NeedsRefreshException nre) {
            try {
                DAOFactory factory = DAOFactory.getDAOFactory(DAOFactory.DOMINO);
                IWebOrganizationDAO dao = factory.getWebOrganizationDAO();
                list = dao.selectAllWebOrganizations(getCorbaAddress(), user.getToken(), user.getCaptive(),
                        getDominoServerName(), getIextensionsPath());
                admin.putInCache(IConstants.WEB_ORGANIZATION_CACHE, list);
            } catch (Exception ex) {
                list = (List) nre.getCacheContent();
                // It is essential that cancelUpdate is called if the
                // cached content is not rebuilt
                admin.cancelUpdate(IConstants.WEB_ORGANIZATION_CACHE);
            }
        }

        List subList = new ArrayList();
        for (Iterator iter = list.iterator(); iter.hasNext();) {
            compareCaptiveOrg(user, subList, iter);

        }
        BeanComparator comp = new BeanComparator("companyName");
        Collections.sort(subList, comp);
        return subList;

    }

    /**
     * @return
     */
    private GeneralCacheAdministrator getOSCacheAdmin() {
        GeneralCacheAdministrator admin = null;

        admin = (GeneralCacheAdministrator) getServletContext().getAttribute(IConstants.OS_CACHE_ADMIN);
        if (admin == null) {
            admin = new GeneralCacheAdministrator();
            getServletContext().setAttribute(IConstants.OS_CACHE_ADMIN, admin);
        }
        return admin;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.novix.portal.framework.service.IGenericService#getContactsByCaptive(com.novix.portal.framework.model.IPortalUser)
     */
    public List getContactsByCaptive(IPortalUser user) {
        GeneralCacheAdministrator admin = getOSCacheAdmin();
        List list;
        try {
            list = (List) admin.getFromCache(IConstants.WEB_CONTACTS_CACHE, DURATION_IN_SECONDS);
        } catch (NeedsRefreshException nre) {
            try {
                DAOFactory factory = DAOFactory.getDAOFactory(DAOFactory.DOMINO);
                IWebContactDAO dao = factory.getWebContactDAO();
                list = dao.selectAllWebContacts(getCorbaAddress(), user.getToken(), user.getCaptive(),
                        getDominoServerName(), getIextensionsPath());
                admin.putInCache(IConstants.WEB_CONTACTS_CACHE, list);
            } catch (Exception ex) {
                list = (List) nre.getCacheContent();
                // It is essential that cancelUpdate is called if the
                // cached content is not rebuilt
                admin.cancelUpdate(IConstants.WEB_CONTACTS_CACHE);
            }
        }
        List subList = new ArrayList();
        for (Iterator iter = list.iterator(); iter.hasNext();) {
            compareCaptive(user, subList, iter);

        }
        BeanComparator comp = new BeanComparator("companyName");
        Collections.sort(subList, comp);
        return subList;

    }

    /*
     * (non-Javadoc)
     * 
     * @see com.novix.portal.framework.service.IGenericService#searchWebOrganizations(com.novix.portal.framework.model.IPortalUser)
     */
    public List searchWebOrganizations(IPortalUser user) {
        return getWebOrganizations(user);
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.novix.portal.framework.service.IGenericService#searchWebOrganizationsByQuery(java.lang.String,
     *      com.novix.portal.framework.model.IPortalUser)
     */
    public List searchWebOrganizationsByQuery(String query, IPortalUser user) {
        DAOFactory factory = DAOFactory.getDAOFactory(DAOFactory.DOMINO);
        IWebOrganizationDAO dao = factory.getWebOrganizationDAO();
        List list = dao.selectAllWebOrganizationsByQuery(query, getCorbaAddress(), user.getToken(), user.getCaptive(),
                getDominoServerName(), getIextensionsPath());
        return list;

    }

    /*
     * (non-Javadoc)
     * 
     * @see com.novix.portal.framework.service.IGenericService#getAllContactsByCaptive(com.novix.portal.framework.model.IPortalUser)
     */
    public List getAllContactsByCaptivePicsOrNone(IPortalUser user) {
        GeneralCacheAdministrator admin = getOSCacheAdmin();
        List list;
        try {
            list = (List) admin.getFromCache(IConstants.WEB_CONTACTS_PICS_OR_NO_CACHE, DURATION_IN_SECONDS);
        } catch (NeedsRefreshException nre) {
            try {
                DAOFactory factory = DAOFactory.getDAOFactory(DAOFactory.DOMINO);
                IWebContactDAO dao = factory.getWebContactDAO();
                list = dao.selectAllWebContactsPicsOrNone(getCorbaAddress(), user.getToken(), user.getCaptive(),
                        getDominoServerName(), getIextensionsPath());
                admin.putInCache(IConstants.WEB_CONTACTS_PICS_OR_NO_CACHE, list);
            } catch (Exception ex) {
                list = (List) nre.getCacheContent();
                // It is essential that cancelUpdate is called if the
                // cached content is not rebuilt
                admin.cancelUpdate(IConstants.WEB_CONTACTS_PICS_OR_NO_CACHE);
            }
        }
        List subList = new ArrayList();
        for (Iterator iter = list.iterator(); iter.hasNext();) {
            compareCaptive(user, subList, iter);

        }
        BeanComparator comp = new BeanComparator("lastName");
        Collections.sort(subList, comp);
        return subList;
    }

    private void compareCaptive(IPortalUser user, List subList, Iterator iter) {
        WebContact element = (WebContact) iter.next();
        for (Iterator iterator = element.getCaptives().iterator(); iterator.hasNext();) {
            String captive = (String) iterator.next();
            if (!StringUtils.isEmpty(captive) && captive.compareToIgnoreCase(user.getCaptive()) == 0)
                subList.add(element);
        }
    }

    private void compareCaptiveOrg(IPortalUser user, List subList, Iterator iter) {
        WebOrganization element = (WebOrganization) iter.next();
        for (Iterator iterator = element.getCaptives().iterator(); iterator.hasNext();) {
            String captive = (String) iterator.next();
            if (!StringUtils.isEmpty(captive) && captive.compareToIgnoreCase(user.getCaptive()) == 0)
                subList.add(element);
        }
    }
}